package server

import (
	"animal/octopus/cache"
	"animal/octopus/common"
	"animal/octopus/config"
	"animal/octopus/mq"
	"sync"

	"github.com/gin-contrib/cors"
	"github.com/gin-gonic/gin"
	log "github.com/sirupsen/logrus"
)

// ------------------------------------------------------------------------------
// singleton
// ------------------------------------------------------------------------------
type Server struct {
}

var instance *Server
var once sync.Once

func Instance() *Server {
	once.Do(func() {
		instance = &Server{}
	})
	return instance
}

// ------------------------------------------------------------------------------
//
// ------------------------------------------------------------------------------
func (server *Server) Init(configFile string) bool {
	common.InitLog()

	if config.Instance().Init(configFile) != nil {
		log.Error("init config failed")
		return false
	}

	if InitDB(config.Instance().Data.Truncate) != nil {
		log.Error("init database failed")
		return false
	}

	if err := cache.Instance().Init(); err != nil {
		log.Error("load all modules failed")
		return false
	}

	if !mq.Instance().Init() {
		log.Error("init mq server failed")
		return false
	}

	return true
}

// ------------------------------------------------------------------------------
//
// ------------------------------------------------------------------------------
func (server *Server) Run() {
	mq.Instance().Run()

	// event loop
	server.runGin()
}

// ------------------------------------------------------------------------------
//
// ------------------------------------------------------------------------------
func (server *Server) runGin() {
	app := gin.Default()

	corsPolicy := cors.New(cors.Config{
		AllowAllOrigins: true,
		AllowHeaders:    []string{"*"},
	})
	app.Use(corsPolicy)

	// prepare routers
	server.BuildRouters(app)

	if nil == app.Run(config.Instance().Data.Listen) {
		log.Fatal("run gin server failed")
	}
}
